package apiroute

import (
	"git.sr.ht/~mil/mobroute/src/db"
	"git.sr.ht/~mil/mobroute/src/utilfuncs"
	"git.sr.ht/~mil/mobsql"
	"time"
)

type RouteParams struct {
	Filter   *SourcesetFilter `yaml:"filter"`
	From     *utilfuncs.Coord `yaml:"from"`
	To       *utilfuncs.Coord `yaml:"to"`
	Time     *time.Time       `yaml:"time"` // Time of departure; if nil, uses now
	CacheDir *string          `yaml:"cache_dir"`

	MaxWalkSeconds     *uint `yaml:"max_walk_seconds"`
	MaxTripSeconds     *uint `yaml:"max_trip_seconds"`
	MaxTransferSeconds *uint `yaml:"max_transfer_seconds"`
	MinTransferSeconds *uint `yaml:"min_transfer_seconds"`
	MaxNTransfers      *uint `yaml:"max_n_transfers"`

	WalkspeedKmHr      *float64 `yaml:"walkspeed_km_hr"`
	TransfersTable     *bool    `yaml:"transfers_table"`
	TransfersGenerated *bool    `yaml:"transfers_generated"`

	DebugFormatting *bool `yaml:"debug_formatting"`

	OutputFormats *[]string `yaml:"output_formats"`
}

type DiagnosticsPerf struct {
	PerfSLoadcompute      string `json:"perf_sloadcompute"`
	PerfSMemloadConns     string `json:"perf_smemload_connections"`
	PerfSMemloadTransfers string `json:"perf_smemload_transfers"`
	PerfSMemloadWalksfrom string `json:"perf_smemload_walksfrom"`
	PerfSMemloadWalksto   string `json:"perf_smemload_walksto"`
	PerfSMemloadConnsverb string `json:"perf_smemload_connsverb"`
	PerfSRoute            string `json:"perf_sroute"`

	PerfNMemTransfers       int `json:"perf_nmemtransfers"`
	PerfNMemWalksfrom       int `json:"perf_nmemwalksfrom"`
	PerfNMemWalksfromNonnil int `json:"perf_nmemwalksfromnonnil"`
	PerfNMemWalksto         int `json:"perf_nmemwalksto"`
	PerfNMemWalkstoNonnil   int `json:"perf_nmemwalkstononnil"`
	PerfNMemConns           int `json:"perf_nmemconns"`
}

type DiagnosticsRoute struct {
	RoutediagNTransfers uint   `json:"route_ntransfers"`
	RoutediagSTotal     uint   `json:"route_stotal"`
	RoutediagSWalk      uint   `json:"route_swalk"`
	RoutediagSTransfer  uint   `json:"route_stransfer"`
	RoutediagSTrip      uint   `json:"route_strip"`
	RoutediagDTotal     string `json:"route_dtotal"`
	RoutediagDWalk      string `json:"route_dwalk"`
	RoutediagDTransfer  string `json:"route_dtransfer"`
	RoutediagDTrip      string `json:"route_dtrip"`
}

type RouteResponse struct {
	RouteLegs        *[]RouteLeg       `json:"route_legs,omitempty"`
	GeoJSON          *[]GeoJSONFeature `json:"geojson,omitempty"`
	DiagnosticsPerf  *DiagnosticsPerf  `json:"diagnostics_perf,omitempty"`
	DiagnosticsRoute *DiagnosticsRoute `json:"diagnostics_route,omitempty"`
	MapURL           *string           `json:"mapurl,omitempty"`
}

type StopDetails struct {
	Time   string `json:"stop_time"`
	Name   string `json:"stop_name"`
	Coords string `json:"stop_coords"`
}

type RouteLeg struct {
	LegType       string `json:"leg_type"` // transfer, walk, or trip
	LegBeginTime  string `json:"leg_begin_time,omitempty"`
	LegBeginTimeS uint   `json:"leg_begin_time_s,omitempty"`
	LegEndTime    string `json:"leg_end_time,omitempty"`
	LegEndTimeS   uint   `json:"leg_end_time_s,omitempty"`
	LegDuration   string `json:"leg_duration"`
	LegDurationS  uint   `json:"leg_duration_s"`
	LegFromCoords string `json:"leg_from_coords"`
	LegToCoords   string `json:"leg_to_coords"`

	// When LegType == "trip" will be present
	TripID            *string                  `json:"trip_id,omitempty"`
	TripRoute         *string                  `json:"trip_route,omitempty"`
	TripRouteHeadsign *string                  `json:"trip_route_headsign,omitempty"`
	TripFrom          *string                  `json:"trip_from,omitempty"`
	TripFromSIDU      *string                  `json:"-"`
	TripToSIDU        *string                  `json:"-"`
	TripTo            *string                  `json:"trip_to,omitempty"`
	TripStops         *[]*StopDetails          `json:"trip_stops,omitempty"`
	TripConnections   *[]*db.ConnectionVerbose `json:"trip_connections,omitempty"`
	TripSource        *int                     `json:"trip_source,omitempty"`

	// When LegType == "walk" wil be present
	TransferFrom     *string  `json:"transfer_from,omitempty"`
	TransferTo       *string  `json:"transfer_to,omitempty"`
	TransferDdwell   *string  `json:"transfer_ddwell,omitempty"`
	TransferDactive  *string  `json:"transfer_dactive,omitempty"`
	TransferDistKM   *float64 `json:"transfer_dist_km,omitempty"`
	TransferCategory *string  `json:"transfer_category,omitempty"`
	TransferSources  *[]int   `json:"transfer_sources,omitempty"`

	// When LegType == "transfer" will be present
	WalkTo     *string  `json:"walk_to,omitempty"`
	WalkFrom   *string  `json:"walk_from,omitempty"`
	WalkDistKm *float64 `json:"walk_dist_km,omitempty"`
}

type GeoJSONFeature struct {
	Type       string            `json:"type"`
	Properties map[string]string `json:"properties,omitempty"`
	Geometry   any               `json:"geometry,omitempty"` // E.g Either GeoJSONGeometry{LineString,Point}
}

type GeoJSONGeometryLineString struct {
	Type        string       `json:"type"` // Always set to "LineString"
	Coordinates [][2]float64 `json:"coordinates"`
}

type GeoJSONGeometryPoint struct {
	Type        string     `json:"type"` // Always set to "Point"
	Coordinates [2]float64 `json:"coordinates"`
}

type SourcesetFilter = mobsql.SourcesetFilter
